<template>
  <div class="form-container">
    <!-- 头部搜索 -->
    <div class="table-head">
      <el-form class="table-form" v-permission="['201004']">
        <el-form-item label="角色名称">
          <el-input v-model="keyWords.name"></el-input>
        </el-form-item>
        <el-form-item label="权限字符">
          <el-input v-model="keyWords.remark"></el-input>
        </el-form-item>
        <el-form-item label="状态">
          <el-select v-model="keyWords.status" placeholder="角色状态" style="width: 110px">
            <el-option label="正常" :value="true"></el-option>
            <el-option label="停用" :value="false"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="创建时间">
          <el-date-picker
            v-model="keyWords.createdAt"
            type="daterange"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
          ></el-date-picker>
        </el-form-item>
        <el-button type="primary" plain icon="Search" @click="handelSearch">搜索</el-button>
        <el-button type="warning" plain icon="Refresh" @click="handelRefresh">重置</el-button>
      </el-form>
      <!-- 增删改查按钮组 -->
      <el-row class="btns">
        <el-button v-permission="['201001']" type="primary" plain icon="Plus" @click="add">增加</el-button>
        <el-button
          type="success"
          plain
          v-permission="['201002']"
          icon="Edit"
          :disabled="multipleSelection.length>1 ||multipleSelection.length===0 "
          @click="edit(null)"
        >修改</el-button>
        <el-button
          type="danger"
          plain
          v-permission="['201003']"
          icon="Delete"
          :disabled="multipleSelection.length===0"
          @click="del"
        >删除</el-button>
        <el-button type="warning" plain icon="Upload" @click="importExcel">导入Excel</el-button>
        <el-button type="success" plain icon="Download" @click="exportExcel">导出Excel</el-button>
      </el-row>
    </div>
    <!-- 表格区域 -->
    <div class="table">
      <el-table :data="rolelist" style="width: 100%" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" />
        <el-table-column label="角色编号" type="index" :index="indexMethod" width="120" />
        <el-table-column label="角色名称" prop="name"></el-table-column>
        <el-table-column label="角色标识" prop="remark"></el-table-column>
        <el-table-column label="角色状态" prop="status">
          <template #default="scope">
            <el-switch
              v-model="scope.row.status"
              class="ml-2"
              inline-prompt
              @change="handleStatusChange(scope.row)"
            />
          </template>
        </el-table-column>
        <el-table-column label="角色描述" prop="description"></el-table-column>
        <el-table-column label="创建时间" prop="createdAt"></el-table-column>
        <el-table-column fixed="right" label="操作" width="260">
          <template #default="scope">
            <el-button
              type="danger"
              v-permission="['201003']"
              size="small"
              icon="Delete"
              @click="del(scope.row)"
            >删除</el-button>
            <el-button
              type="warning"
              v-permission="['201002']"
              size="small"
              icon="Edit"
              @click="edit(scope.row)"
            >修改</el-button>

            <el-button
              type="warning"
              v-permission="['201002']"
              size="small"
              icon="Setting"
              @click="permission(scope.row)"
            >权限</el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 表格分页 -->
      <table-pagination
        :pagination="pagination"
        @handleSizeChange="handleSizeChange"
        @handleCurrentChange="handleCurrentChange"
      />
    </div>
    <!-- 添加或修改角色配置对话框 -->
    <el-dialog v-model="dialogVisible" :title="title" width="30%" :before-close="handleClose">
      <el-form ref="ruleFormRef" :model="RoleForm" :rules="rules" label-width="120px">
        <el-form-item label="角色名称:" prop="name">
          <el-input v-model="RoleForm.name"></el-input>
        </el-form-item>
        <el-form-item label="角色标识:" prop="remark">
          <el-input v-model="RoleForm.remark"></el-input>
        </el-form-item>
        <el-form-item label="角色描述:" prop="description">
          <el-input v-model="RoleForm.description"></el-input>
        </el-form-item>
        <el-form-item label="角色状态:" prop="status">
          <el-radio-group v-model="RoleForm.status">
            <el-radio :label="true">正常</el-radio>
            <el-radio :label="false">停用</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="resetForm(RoleForm)">取消</el-button>
          <el-button type="primary" @click="submitForm(ruleFormRef)">确定</el-button>
        </span>
      </template>
    </el-dialog>
    <!-- 导入Excel弹框 -->
    <import-data
      :showExcel="showExcel"
      :rolelistAll="rolelistAll"
      @onSucess="onSucess"
      @cancel="cancel"
      @confirm="confirm"
      v-permission="['201005']"
    ></import-data>
    <!-- 导出Excel弹框 -->
    <export-data
      :showExcelOut="showExcelOut"
      :rolelistAll="rolelistAll"
      :excleConfig="ROLE_RELTIVES"
      @cancel="cancel"
      @confirm="confirm"
      v-permission="['201006']"
    ></export-data>
    <!-- 树形菜单 -->
    <el-dialog
      :draggable="false"
      @closed="closed"
      :open-delay="300"
      v-model="showTree"
      :title="currentRole"
      width="30%"
    >
      <el-tree
        ref="treeRef"
        :data="TreeRoles"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-expanded-keys="[2, 3]"
        :default-checked-keys="defaultCheckedKeys"
        :props="defaultPropss"
        @check="handleNodeClick"
      />
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="showTree = false">取消</el-button>
          <el-button type="primary" @click="confirmPrimission">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import ImportData from '@/components/Excel/importData.vue'
import ExportData from '@/components/Excel/exportData.vue'
// import Tree from '@/components/Tree'
import { generater } from '@/components/Excel/utils.js'
import { ROLE_RELTIVES } from '@/excleConfig'
import TablePagination from '@/components/sysCommom/tablePagination.vue'
import { reactive, ref } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import { tree, isCheacked } from '@/utils/tree.js'
import { getMenulists } from '@/api/menu.js'
import { getRemarks } from '@/api/user'
import {
  getRolelist,
  UpdateRole,
  SearchRole,
  addRole,
  delRole,
  addRoleList,
  getRolelistAll,
  getTreeRolesByRid,
  updatePrimission,
} from '@/api/sysRole.js'
import { ElMessage, ElMessageBox } from 'element-plus'
const store = new useStore()
const router = new useRouter()
const defaultPropss = {
  children: 'children',
  label: 'name',
}

// 树形结构实例方法
const treeRef = ref()
// 定义树形结构的弹框显示与隐藏
const showTree = ref(false)
//  树形结构的弹框 标题
const currentRole = ref('')
//  树形结构的数据
const TreeRoles = ref([])
const currentTreeRolesId = ref('')
// 默认勾选
const defaultCheckedKeys = ref([])
// 勾选的节点
const halfCheckedNodesList = ref([])
// 获取树形结构数据
const getTreeRoles = async (id) => {
  // 获取角色对应的权限编码
  const { data: remarks } = await getTreeRolesByRid({ id })
  const { data } = await getMenulists()
  // 获取所有的权限
  // console.log(data)
  TreeRoles.value = tree(data)
  //判断是否为true 添加到勾选中

  defaultCheckedKeys.value = isCheacked(remarks, TreeRoles.value)
}
// 树形结构弹出框 关闭回调事件
const closed = () => {
  // 清空数据 防止下次点开还有数据
  defaultCheckedKeys.value = []
}
// 处理勾选的事件
const handleNodeClick = async (a, b) => {
  // 获取选中的节点的数组和当前的节点
  let m1 = b.checkedNodes
  let m2 = b.halfCheckedNodes
  let arr = m1.map((item) => {
    return {
      mid: item.id,
      prim: item.remark,
    }
  })
  let arr2 = m2.map((item) => {
    return {
      mid: item.id,
      prim: item.remark,
    }
  })
  halfCheckedNodesList.value = [...arr2, ...arr]
  // console.log(halfCheckedNodesList)
}
// 确认授权
const confirmPrimission = async () => {
  // 关闭弹框
  showTree.value = false
  // 执行授权
  // 获取当前的操作对象currentTreeRolesId
  // 将数组和currentTreeRolesId 传给后台 进行添加
  const data = await updatePrimission({
    rid: currentTreeRolesId.value,
    midPrims: halfCheckedNodesList.value,
  })
  if (data.code == 200) {
    // 不理解为什么使用 不行
    // await store.dispatch('user/getRemarks')
    const { data: remarks } = await getRemarks()
    store.commit('user/setRemarks', remarks)
    ElMessage.success(data.msg)
  }
  // router.go(0)
}
// 数据列表
const rolelist = ref([])
// 导出数据列表
const rolelistAll = ref([])
// 弹框显示隐藏
const dialogVisible = ref(false)
// 弹出框标题
const title = ref('添加角色')
// 表单实例对象
const ruleFormRef = ref()
// 显示导入Excel
let showExcel = ref(false)
// 显示导出Excel
let showExcelOut = ref(false)
// 数据绑定
const RoleForm = reactive({
  id: undefined,
  name: '',
  remark: '',
  description: '',
  status: true,
})
// 批量选择容器
const multipleSelection = ref([])
// 存储修改对象
const multipleSelectionObj = ref([])
// 分页参数
const pagination = reactive({
  total: 0,
  currentPage: 1,
  pageSize: 8,
})
// 搜索词
let keyWords = reactive({
  name: '',
  remark: '',
  status: '',
  createdAt: null || [],
})
// 处理关闭弹框
const handleClose = () => {
  resetForm(RoleForm)
  dialogVisible.value = false
  defaultCheckedKeys.value = []
}
// 添加方法
const add = () => {
  title.value = '添加角色'
  dialogVisible.value = true
}
// 修改信息
const edit = (row) => {
  title.value = '修改角色'
  const roleIds = row ? row : multipleSelectionObj.value[0]
  RoleForm.id = roleIds.id
  RoleForm.name = roleIds.name
  RoleForm.remark = roleIds.remark
  RoleForm.description = roleIds.description
  RoleForm.status = roleIds.status
  dialogVisible.value = true
}

// 开关事件
const handleStatusChange = async (roleObj) => {
  const data = await UpdateRole({
    id: roleObj.id,
    status: roleObj.status,
  })
  // await delRole({ ids: roleObj.id })

  if (data.code === 200) {
    ElMessage.success(data.msg)
  }
}
// 搜索事件
const handelSearch = async () => {
  if (keyWords.createdAt.length === 2) {
    keyWords['begin'] = dateFormat(keyWords.createdAt[0])
    keyWords['end'] = dateFormat(keyWords.createdAt[1])
  }

  const { data } = await SearchRole(keyWords)
  if (data.rows.length > 0) {
    rolelist.value = data.rows
    pagination.total = data.count
    ElMessage.success('查询成功')
  } else {
    rolelist.value = data.rows
    ElMessage.error('暂无查询结果')
  }
}
// 搜索条件重置事件
const handelRefresh = () => {
  keyWords.name = ''
  keyWords.remark = ''
  keyWords.status = ''
  keyWords.createdAt = []
  keyWords['begin'] = ''
  keyWords['end'] = ''
  roles()
}
// 获取角色
const roles = async () => {
  const {
    data: { count, rows },
  } = await getRolelist(pagination)
  rolelist.value = rows
  pagination.total = count
  // console.log(rolelist.value)
}
roles()
// 删除角色
const del = (row) => {
  ElMessageBox.confirm('确定要永久删除此条记录，操作不可恢复?', '警告', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  })
    .then(async () => {
      const roleIds = row.id || multipleSelection.value
      // console.log(roleIds)
      const data = await delRole({ ids: roleIds })

      if (data.code === 200) {
        ElMessage.success(data.msg)
        roles()
      }
    })
    .catch(() => {})
}
// 角色权限
const permission = (row) => {
  // 显示控件基本信息
  showTree.value = true
  currentRole.value = row.name
  // 根据row.id 找到角色的权限信息
  // 定义全局id 方便修改
  currentTreeRolesId.value = row.id
  getTreeRoles(row.id)
  // 传递给子组件
}
// 表单排序
const indexMethod = (index) => {
  return (pagination.currentPage - 1) * pagination.pageSize + index + 1
}
// 批量删除选择事件
const handleSelectionChange = (selection) => {
  const ids = selection.map((item) => item.id)
  multipleSelectionObj.value = selection
  multipleSelection.value = ids
}
// 表单提交事件
const submitForm = (formEl) => {
  formEl.validate(async (valid) => {
    if (!valid) return
    let data
    if (!RoleForm.id) {
      // 添加
      data = await addRole(RoleForm)
    } else {
      // 修改
      data = await UpdateRole(RoleForm)
    }
    if (data.code === 200) {
      ElMessage.success(data.msg)
      resetForm(RoleForm)
      roles()
    }
    dialogVisible.value = false
    // router.go(0)
  })
}
// 导入Excel显示弹框
const importExcel = () => {
  showExcel.value = true
}
// 导出Excel显示弹框 传递数据
const exportExcel = async () => {
  const { data } = await getRolelistAll()
  rolelistAll.value = data
  showExcelOut.value = true
}
// 接收子组件取消 关闭弹出框的事件
const cancel = () => {
  showExcel.value = false
  showExcelOut.value = false
}
// 接收子组件的确定事件 关闭弹框
const confirm = () => {
  showExcel.value = false
  showExcelOut.value = false
}
//导入excel数据 成功的回调函数
const onSucess = async (excelDate) => {
  //excel 数据
  const { results } = excelDate
  const res = generater(results, ROLE_RELTIVES)
  // 批量插入接口
  const data = await addRoleList({ roles: res, condition: 'name' })
  if (data.code === 200) {
    confirm()
    ElMessage.success(`一共插入${data.inserCount}条数据`)
    roles()
  }
}
// 表单重置
const resetForm = (object) => {
  for (const key in object) {
    if (Object.hasOwnProperty.call(object, key)) {
      if (object[key] != true) object[key] = ''
    }
  }
  dialogVisible.value = false
}
// 表单验证规则
const rules = reactive({
  name: [
    {
      required: true,
      message: '请输入角色名称',
      trigger: 'blur',
    },
    {
      min: 3,
      max: 20,
      message: '请输入 3 到 20 个字符',
      trigger: 'blur',
    },
  ],
  remark: [
    {
      required: true,
      message: '请输入角色标识',
      trigger: 'blur',
    },
    {
      min: 3,
      max: 20,
      message: '请输入 3 到 20 个字符',
      trigger: 'blur',
    },
  ],
  description: [
    {
      required: true,
      message: '请输入角色描述',
      trigger: 'blur',
    },
    {
      max: 50,
      message: '不能超过50个字符',
      trigger: 'blur',
    },
  ],
  status: [
    {
      required: true,
      message: '请选择角色状态',
      trigger: 'blur',
    },
  ],
})
// 时间的格式化
const dateFormat = (dateData) => {
  var date = new Date(dateData)
  var y = date.getFullYear()
  var m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  var d = date.getDate()
  d = d < 10 ? '0' + d : d
  const time = y + '-' + m + '-' + d
  return time
}
// 分页处理-页码改变
const handleSizeChange = (val) => {
  pagination.currentPage = 1
  pagination.pageSize = val
  roles()
}
// 分页处理-每页条数改变
const handleCurrentChange = (val) => {
  pagination.currentPage = val
  roles()
}
</script>
<style lang="less" scoped>
.el-form .el-form-item {
  margin-right: 15px;
}
.form-container {
  margin: 15px;
}
.btns {
  margin: 10px 0;
}
.table-form {
  display: flex;
}
.pagination {
  margin-top: 15px;
  float: right;
}
</style>